home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / archives / com / internet / stik / gls002b5.zoo / config.c next >
C/C++ Source or Header  |  1997-09-21  |  8KB  |  332 lines

  1. #include <osbind.h>
  2. #include <mintbind.h>
  3. #include <ctype.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #define DAEMON            /* to get "int caller_pid, " */
  8. #include "global.h"
  9.  
  10. #define SYSVAR_bootdev    (*((short *)0x446UL))
  11.  
  12.  
  13. typedef struct {
  14.   void *mem;
  15.   size_t size;
  16.   int n_entries;
  17.   int n_slots;
  18. } GrowBuf;
  19.  
  20. typedef struct {
  21.   int name_off;
  22.   int val_off;
  23. } Var;
  24.  
  25.  
  26. static GrowBuf gvars = {0, sizeof(Var), 0, 0},
  27.            gdata = {0, sizeof(char), 0, 0};
  28. static char *data = 0;
  29. static Var *vars = 0;
  30.  
  31. char cfg_filename[160] = "A:\\STIK_CFG\\DEFAULT.CFG";
  32. static char stikdir_dat[] = "A:\\STIK_DIR.DAT";
  33. static char default_config[] = "ALLOCMEM = 50000\n";
  34.  
  35.  
  36. /* growbuf() --rRequest space for |new_slots| new entries in the
  37.    GrowBuf |G|, reallocating the buffer if necessary */
  38. static int growbuf(GrowBuf *G, int new_slots)
  39. {
  40.   if (!G->mem) {
  41.     G->mem = (void *)Mxalloc(G->size * new_slots, 3);
  42.     if (!G->mem) return 0;
  43.     G->n_slots = new_slots; G->n_entries = 0;
  44.     return 1;
  45.   }
  46.   if (G->n_entries + new_slots <= G->n_slots)
  47.     return 1;
  48.  
  49.   {
  50.     int n = G->n_slots; void *v;
  51.  
  52.     while (n < G->n_entries + new_slots) n *= 2;
  53.     v = (void *)Mxalloc(G->size * n, 3);
  54.     if (!v) return 0;
  55.     memcpy(v, G->mem, G->size * G->n_entries);
  56.     Mfree(G->mem);
  57.     G->mem = v; G->n_slots = n;
  58.     return 1;
  59.   }
  60. }
  61. #define GROWBUF(G, slots, var) \
  62.     (growbuf(&(G), slots) ? (((var) = (G).mem), 1) : 0)
  63.  
  64. /* set_var() -- add variable |name| with value |value| (or change value
  65.    if variable is already present).  Returns 1 on success, 0 on failure. */
  66. static int set_var(char *name, char *value)
  67. {
  68.   int i;
  69.  
  70.   if (!GROWBUF(gvars, 1, vars) ||
  71.       !GROWBUF(gdata, strlen(name) + strlen(value) + 2, data))
  72.     return 0;
  73.  
  74.   for (i = 0; i < gvars.n_entries; i++) {
  75.     if (!stricmp(name, data + vars[i].name_off)) {
  76.       vars[i].val_off = gdata.n_entries;
  77.       strcpy(data + gdata.n_entries, value);
  78.       gdata.n_entries += strlen(value) + 1;
  79.       return 1;
  80.     }
  81.   }
  82.  
  83.   i = gvars.n_entries++;
  84.   vars[i].name_off = gdata.n_entries;
  85.   strcpy(data + gdata.n_entries, name);
  86.   gdata.n_entries += strlen(name) + 1;
  87.   vars[i].val_off = gdata.n_entries;
  88.   strcpy(data + gdata.n_entries, value);
  89.   gdata.n_entries += strlen(value) + 1;
  90.   return 1;
  91. }
  92.  
  93. /* kill_tws() -- strip trailing whitespace from string */
  94. static void kill_tws(char *s)
  95. {
  96.   register char *t = s + strlen(s);
  97.  
  98.   while (t > s && isspace(t[-1])) t--;
  99.   *t = '\0';
  100. }
  101.  
  102.  
  103. static int get_bootdrive(void)
  104. {
  105.   return (int)SYSVAR_bootdev;
  106. }
  107.  
  108. static int find_config_file(void)
  109. {
  110.   register long l;
  111.   register int n, fd, boot;
  112.   register char *s;
  113.  
  114.   boot = Supexec(get_bootdrive);
  115.   cfg_filename[0] += boot;
  116.   stikdir_dat[0] += boot;
  117.  
  118.   if ((l = Fopen(stikdir_dat, 0)) < 0)
  119.     return 1;
  120.   fd = (int)(short)l;
  121.   if ((n = Fread(fd, sizeof(cfg_filename), cfg_filename)) < 0) {
  122.     Fclose(fd);
  123.     Cconws("Error reading STIK_DIR.DAT; using default path\r\n");
  124.     return 1;
  125.   }
  126.   if (n >= sizeof(cfg_filename))
  127.     n = sizeof(cfg_filename) - 1;
  128.   if (!(s = strchr(cfg_filename, '\n')))
  129.     s = cfg_filename + n;
  130.   if (s[-1] == '\r')
  131.     s--;
  132.   *s = 0;
  133.   /* Incompatibility:  The STiK docs imply that you can change the
  134.      config file name via STIK_DIR.DAT, but then say to include only the
  135.      new path.  I'm gonna handle it this way:  if the line read from
  136.      STIK_DIR.DAT has a trailing '/' or '\', assume it's a path and
  137.      append "DEFAULT.CFG"; otherwise, assume it's the whole file name
  138.      and return it untouched. */
  139.   if (s[-1] == '\\' || s[-1] == '/')
  140.     strcpy(s, "DEFAULT.CFG");
  141.   return 1;
  142. }
  143.  
  144. #define NEXT_LINE()    {while (*s) s++; while (!*s) s++;}
  145.  
  146. int load_config_file()
  147. {
  148.   char *file_data;
  149.   register char *s, *t;
  150.   unsigned long filesize;
  151.   long l;
  152.   int n, fd;
  153.   struct stat S;
  154.  
  155.   if (Psem_create(CONFIG_SEM) < 0) {
  156.     Cconws("Unable to get config semaphore\r\n");
  157.     return -1;
  158.   }
  159.   Psem_release(CONFIG_SEM);
  160.  
  161.   if (!GROWBUF(gvars, 100, vars) || !GROWBUF(gdata, 5000, data)) {
  162.     Cconws("Cannot get memory for STiK vars\r\n");
  163.     return -1;
  164.   }
  165.  
  166.   if (!find_config_file()) {    /* Okay, so I'm paranoid... ;) */
  167.     Cconws("Unable to find config file\r\n");
  168.     return -1;
  169.   }
  170.   if (Fxattr(0, cfg_filename, &S)) {
  171.     Cconws("Config file ");
  172.     Cconws(cfg_filename);
  173.     Cconws(" does not exist; using built-in defaults...\r\n");
  174.     
  175.     if (!set_var("ALLOCMEM", "50000")) return -1;
  176.     if (!set_var("GLUESTIK_TRACE", "0")) return -1;
  177.     return 0;
  178.   }
  179.  
  180.   filesize = S.st_size;
  181.   Cconws("Reading config file ");
  182.   Cconws(cfg_filename);
  183.   Cconws("...\r\n");
  184.  
  185.   file_data = (char *)Mxalloc(filesize + 2, 3);
  186.   if (!file_data) {
  187.     Cconws("Cannot get memory to read config file\r\n");
  188.     return -1;
  189.   }
  190.   file_data[filesize] = file_data[filesize+1] = '\0';
  191.  
  192.   if ((l = Fopen(cfg_filename, 0)) < 0) {
  193.     Cconws("Error opening config file ");
  194.     Cconws(cfg_filename);
  195.     Cconws("\r\n");
  196.     return -1;
  197.   }
  198.   fd = (int)(short)l;
  199.  
  200.   s = file_data;
  201.   while ((n = Fread(fd, filesize, s)) > 0)
  202.     s += n;
  203.   if (n < 0) {
  204.     Cconws("Error reading config file ");
  205.     Cconws(cfg_filename);
  206.     Cconws("\r\n");
  207.     Mfree(file_data);
  208.     return -1;
  209.   }
  210.   Fclose(fd);
  211.   *s = 0;
  212.  
  213.   /* Split off all lines */
  214.   for (s = file_data; s < file_data + filesize; s++) {
  215.     if (*s == '\r' || *s == '\n')
  216.       *s = 0;
  217.   }
  218.  
  219.   s = file_data;
  220.   while (s < file_data + filesize) {
  221.  
  222.     /* Skip blank lines and comments */
  223.     while (*s && isspace(*s)) s++;
  224.     if (!*s || *s == '#') {
  225.       NEXT_LINE();
  226.       continue;
  227.     }
  228.  
  229.     /* If no '=', variable is "true" */
  230.     t = strchr(s, '=');
  231.     if (!t) {
  232.       kill_tws(s);
  233.       t = "1";
  234.       goto setit;
  235.     }
  236.  
  237.     *t++ = 0;
  238.     kill_tws(s);
  239.     while (*t && isspace(*t)) t++;
  240.     /* Empty value means variable is "false" */
  241.     if (!*t) {
  242.       t = "0";
  243.       goto setit;
  244.     }
  245.  
  246.     kill_tws(t);
  247.   setit:
  248.     if (set_var(s, t)) { NEXT_LINE(); continue; }
  249.  
  250.     Cconws("Unable to set variable \"");
  251.     Cconws(s);
  252.     Cconws("\"\r\n");
  253.     Mfree(file_data);
  254.     return -1;
  255.   }
  256.  
  257.   Mfree(file_data);
  258.   return 0;
  259. }
  260.  
  261. #if 0
  262. extern int caller_pid;        /* from transdmn.c */
  263. #endif
  264.  
  265. char* do_getvstr(int caller_pid, char *var)
  266. {
  267.   register int n;
  268.  
  269.   if (!stricmp(var, "CDVALID")) {
  270. #ifdef DEBUG
  271.       LOG(caller_pid, DBG_SYSCALL,
  272.       "Special case:  getvstr(\"CDVALID\") returns \"0\"");
  273. #if 0
  274.       debug("s", "Special case:  getvstr(\"CDVALID\") returns \"0\"");
  275. #endif
  276. #endif
  277.     return "0";
  278.   }
  279.  
  280.   Psem_obtain(CONFIG_SEM);
  281.  
  282.   for (n = 0; n < gvars.n_entries; n++) {
  283.     if (stricmp(var, data + vars[n].name_off) == 0) {
  284. #ifdef DEBUG
  285.       LOG(caller_pid, DBG_SYSCALL, "getvstr(\"%s\") returns \"%s\"",
  286.       var, data + vars[n].val_off);
  287. #if 0
  288.       debug("sssss", "getvstr(\"", var, "\") returns \"",
  289.         data + vars[n].val_off, "\"");
  290. #endif
  291. #endif
  292.       Psem_release(CONFIG_SEM);
  293.       return data + vars[n].val_off;
  294.     }
  295.   }
  296.  
  297. #ifdef DEBUG
  298.   LOG(caller_pid, DBG_SYSCALL, "getvstr(\"%s\") returns \"0\"", var);
  299. #if 0
  300.   debug("sss", "getvstr(\"", var, "\") returns \"0\"");
  301. #endif
  302. #endif
  303.   Psem_release(CONFIG_SEM);
  304.   return "0";
  305. }
  306.  
  307. int16 do_setvstr(int caller_pid, char *vs, char *value)
  308. {
  309.   int n;
  310.  
  311.   Psem_obtain(CONFIG_SEM);
  312.   n = set_var(vs, value);
  313. #ifdef DEBUG
  314.   LOG(caller_pid, (n ? DBG_SYSCALL : DBG_ERROR),
  315.       "setvstr(\"%s\", \"%s\") returns %d", vs, value, n);
  316. #if 0
  317.   debug("sssssd", "setvstr(\"", vs, "\", \"", value, "\") returns ", n);
  318. #endif
  319. #endif
  320.   Psem_release(CONFIG_SEM);
  321.   return n;
  322. }
  323.  
  324.  
  325. void cleanup_config()
  326. {
  327.   if (gvars.mem) Mfree(gvars.mem);
  328.   if (gdata.mem) Mfree(gdata.mem);
  329.   Psem_obtain(CONFIG_SEM);    /* We have to own the semaphore before we can */
  330.   Psem_destroy(CONFIG_SEM);    /*   destroy it. */
  331. }
  332.